package org.telegram.bot.base;

import com.alibaba.fastjson2.JSONObject;
import com.ruoyi.common.utils.spring.SpringUtils;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.CollectionUtils;
import org.telegram.bot.emums.BotCommonEnums;
import org.telegram.bot.handle.IMessageHandle;
import org.telegram.bot.handle.service.MessageHandleImpl;
import org.telegram.telegrambots.longpolling.BotSession;
import org.telegram.telegrambots.longpolling.interfaces.LongPollingUpdateConsumer;
import org.telegram.telegrambots.longpolling.starter.SpringLongPollingBot;
import org.telegram.telegrambots.longpolling.util.LongPollingSingleThreadUpdateConsumer;
import org.telegram.telegrambots.meta.api.methods.botapimethods.BotApiMethod;
import org.telegram.telegrambots.meta.api.objects.Update;
import org.telegram.telegrambots.meta.exceptions.TelegramApiException;
import org.telegram.telegrambots.meta.generics.TelegramClient;

import java.io.Serializable;

/**
 * 自定义的 Spring 长轮询 Telegram Bot 实现类
 * @author wyx
 * @date 2024/11/10 10:05
 */
@Slf4j
public class CustomSpringLongPollingBot implements SpringLongPollingBot, LongPollingSingleThreadUpdateConsumer {
    
    // 消息处理接口实例
    private final IMessageHandle messageHandle;
    
    // Telegram 客户端实例
    private final TelegramClient telegramClient;
    
    // Bot 的 Token
    private final String token;
    
    // Bot 的唯一标识符
    private final String botId;
    
    // Bot 会话实例
    @Setter
    @Getter
    private BotSession botSession;
    
    /**
     * 构造函数，初始化 Bot 实例
     *
     * @param telegramClient Telegram 客户端实例
     * @param token          Bot 的 Token
     * @param botId          Bot 的唯一标识符
     */
    public CustomSpringLongPollingBot(TelegramClient telegramClient, String token, String botId) {
        // 从 Spring 上下文中获取消息处理实现类
        messageHandle = SpringUtils.getBean(MessageHandleImpl.class);
        this.telegramClient = telegramClient;
        this.token = token;
        this.botId = botId;
    }

    /**
     * 获取 Bot 的 Token
     *
     * @return Bot 的 Token
     */
    @Override
    public String getBotToken() {
        return token;
    }
    
    /**
     * 获取更新消费者实例
     *
     * @return 更新消费者实例
     */
    @Override
    public LongPollingUpdateConsumer getUpdatesConsumer() {
        return this;
    }
    
    /**
     * 处理接收到的更新
     *
     * @param update 接收到的更新对象
     */
    @Override
    public void consume(Update update) {
        // 记录接收到的消息
        log.info("消息：{}", JSONObject.toJSONString(update));
        
        // 如果更新包含消息
        if (update.hasMessage()) {
            var message = update.getMessage();
            var chat = message.getChat();
            
            // 判断是否是频道
            if (BotCommonEnums.CHAT_TYPE_CHANNEL.equals(chat.getType())) {
                return;
            }
            
            // 机器人指令处理
            if (message.hasEntities() &&
                BotCommonEnums.MESSAGE_ENTITY_BOT_COMMAND.equals(message.getEntities().get(0).getType())) {
                messageHandle.botCommand(update, chat.getId(), botId);
            }
            // 转发的消息处理
            else if (message.getForwardFromChat() != null) {
                messageHandle.forwardFromChat(update, chat.getId(), botId);
            }
            // 用户退群处理
            else if (message.getLeftChatMember() != null) {
                messageHandle.leftChat(update, chat.getId(), botId);
            }
            // 用户加群处理
            else if (!CollectionUtils.isEmpty(message.getNewChatMembers())) {
                messageHandle.newChatMembers(update, chat.getId(), botId);
            }
            // 群组类型发生改变: 组迁移到超级组处理
            else if (message.getMigrateToChatId() != null) {
                messageHandle.groupToSuperGroup(update.getMessage().getChat(), chat.getId(), message.getMigrateToChatId(), botId);
            }
            // 其他消息处理
            else {
                messageHandle.message(update, chat.getId(), botId);
            }
        }
        // 如果更新包含编辑后的消息
        else if (update.hasEditedMessage()) {
            messageHandle.editedMessage(update, update.getEditedMessage().getChatId(), botId);
        }
        // 机器人自己的事件处理
        else if (update.hasMyChatMember()) {
            var myChatMember = update.getMyChatMember();
            var oldStatus = myChatMember.getOldChatMember().getStatus();
            var newStatus = myChatMember.getNewChatMember().getStatus();
            var chatType = myChatMember.getChat().getType();
            
            if (BotCommonEnums.CHAT_EVENT_LEFT.equals(oldStatus) &&
                (BotCommonEnums.CHAT_EVENT_MEMBER.equals(newStatus) || BotCommonEnums.CHAT_EVENT_ADMINISTRATOR.equals(newStatus))) {
                // 机器人加入群
                messageHandle.botJoinGroup(update, myChatMember.getChat().getId(), botId);
            } else if (BotCommonEnums.CHAT_EVENT_MEMBER.equals(oldStatus) && BotCommonEnums.CHAT_EVENT_LEFT.equals(newStatus)) {
                // 机器人被移除群
                messageHandle.botLeftGroup(update, myChatMember.getChat().getId(), botId);
            } else if (BotCommonEnums.CHAT_TYPE_CHANNEL.equals(chatType) && myChatMember.getNewChatMember() != null) {
                // 机器人加入频道
                messageHandle.botJoinGroup(update, myChatMember.getChat().getId(), botId);
            } else if (BotCommonEnums.CHAT_EVENT_KICKED.equals(newStatus)) {
                // 机器人被从频道中移除
                messageHandle.botLeftGroup(update, myChatMember.getChat().getId(), botId);
            } else if (BotCommonEnums.CHAT_EVENT_MEMBER.equals(oldStatus) && BotCommonEnums.CHAT_EVENT_ADMINISTRATOR.equals(newStatus)) {
                // 机器人被设置为管理员
                messageHandle.botAddAdmin(update, myChatMember.getChat().getId(), botId);
            } else if (BotCommonEnums.CHAT_EVENT_ADMINISTRATOR.equals(oldStatus) && BotCommonEnums.CHAT_EVENT_MEMBER.equals(newStatus)) {
                // 机器人被取消管理员
                messageHandle.botCancelAdmin(update, myChatMember.getChat().getId(), botId);
            } else if (BotCommonEnums.CHAT_EVENT_RESTRICTED.equals(newStatus)) {
                // 机器人被权限被改变
                // 这里可以添加具体的处理逻辑
            }else{
                log.error("未捕获机器人事件：{}", JSONObject.toJSONString(update));
            }
        }
        // 开启群审核时：有用户加群申请
        else if (update.getChatJoinRequest() != null) {
            messageHandle.chatJoinRequest(update.getChatJoinRequest(), botId);
        }
        // 未捕获的信息处理
        else {
            log.error("未捕获信息：{}", JSONObject.toJSONString(update));
        }
    }
    
    /**
     * 发送消息
     *
     * @param method 发送的消息方法
     * @param <T>    返回结果的类型
     * @param <Method> 发送的方法类型
     * @return 发送结果
     * @throws TelegramApiException 如果发送过程中出现异常
     */
    public <T extends Serializable, Method extends BotApiMethod<T>> T execute(Method method) throws TelegramApiException {
        return telegramClient.execute(method);
    }
    
    /**
     * 异步发送消息
     *
     * @param method 发送的消息方法
     * @param <T>    返回结果的类型
     * @param <Method> 发送的方法类型
     * @throws TelegramApiException 如果发送过程中出现异常
     */
    public <T extends Serializable, Method extends BotApiMethod<T>> void executeAsync(Method method) throws TelegramApiException {
        telegramClient.executeAsync(method);
    }
}
